#include "TcpServer.h"
#include "ui_TcpServer.h"
#include <QHostInfo>
#include <QHostAddress>

TcpServer::TcpServer(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::TcpServer)
{
    ui->setupUi(this);

    initSlotData();
}

TcpServer::~TcpServer()
{
    delete ui;
}

void TcpServer::initSlotData()
{
    if(mTcpServer == nullptr)
    {
        mTcpServer = new QTcpServer(this);
    }

    ui->lineEdit_listenIP->setText(getLocalIP());
    //设置标记和状态显示为没有连接状态
    ui->label_socketState->setText("socket状态: ");
    mListenState = false;

    //响应新客户端接入的信号
    connect (mTcpServer, &QTcpServer::newConnection , this, &TcpServer::onNewConnection) ;


}

QString TcpServer::getLocalIP()
{
    //获取本机IPv4地址
    QString hostName=QHostInfo::localHostName() ;//本地主机名
    QHostInfo hostInfo=QHostInfo::fromName (hostName) ;

    QString localIP="";
    QList<QHostAddress> addList=hostInfo.addresses () ;
    if (!addList. isEmpty())
    {
        for (int i=0; i <addList.count() ;i++)
        {
            QHostAddress aHost=addList.at(i) ;
            if (QAbstractSocket::IPv4Protocol == aHost. protocol())
            {
                localIP=aHost. toString() ;
                break;
            }
        }
    }

    return localIP;
}

void TcpServer::onNewConnection()
{
    mTcpSocket = mTcpServer->nextPendingConnection(); // 获取socket

    onClientConnected();
    onSocketStateChanged(mTcpSocket->state());
    connect (mTcpSocket,&QTcpSocket::disconnected, this, &TcpServer::onClientDisconnected) ;

    connect (mTcpSocket, &QTcpSocket::stateChanged,this, &TcpServer::onSocketStateChanged) ;

    connect (mTcpSocket, &QTcpSocket::readyRead, this,  &TcpServer::onSocketReadyRead) ;
}

void TcpServer::onSocketStateChanged(QAbstractSocket::SocketState socketState)
{
    switch (socketState)
    {
    case QAbstractSocket::UnconnectedState:
        ui->label_socketState->setText ("socket状态: UnconnectedState") ;
        break;
    case QAbstractSocket::HostLookupState:
        ui->label_socketState->setText ("socket状态: HostLookupState") ;
        break;
    case QAbstractSocket::ConnectingState:
        ui->label_socketState->setText ("socket状态: ConnectingState") ;
        break;
    case QAbstractSocket::ConnectedState:
        ui->label_socketState->setText ("socket状态: ConnectedState") ;
        break;
    case QAbstractSocket::BoundState:
        ui->label_socketState->setText ("socket状态: BoundState") ;
        break;
    case QAbstractSocket::ClosingState:
        ui->label_socketState->setText ("socket状态: ClosingState") ;
        break;
    case QAbstractSocket::ListeningState:
        ui->label_socketState->setText ("socket状态: ListeningState") ;
        break;
    }
}

void TcpServer::onClientConnected()
{
    //客户端连接时
    ui->plainTextEdit->appendPlainText ("**client socket connected") ;
    ui->plainTextEdit->appendPlainText ("**peer address:"+ mTcpSocket->peerAddress().toString()) ;
    ui ->plainTextEdit->appendPlainText ("**peer port:"+QString::number(mTcpSocket->peerPort())) ;
}

void TcpServer::onClientDisconnected()
{
    //客户端断开时
    ui->plainTextEdit->appendPlainText ("**client socket disconnected") ;
    mTcpSocket->deleteLater() ;
    mTcpSocket = nullptr;
}

void TcpServer::onSocketReadyRead()
{
    //读取缓冲区行文本
    while (mTcpSocket->canReadLine())
    {
          ui ->plainTextEdit->appendPlainText ("[in] "+mTcpSocket->readLine()) ;
    }
}


void TcpServer::on_pushButton_startListen_clicked()
{
    if(mListenState)
    {
        mListenState = false;
        ui->pushButton_startListen->setText("开始监听");
        //停止监听
        if (mTcpServer->isListening()) //tcpServer 正在监听
        {
            ui->plainTextEdit->appendPlainText ("**停止监听...") ;
            mTcpServer->close() ;//停止监听
            ui->label_socketState->setText ("socket状态: UnconnectedState");
        }
    }
    else
    {
        mListenState = true;
        //开始监听
        QString IP=ui->lineEdit_listenIP->text();//IP地址.
        quint16 port=ui->lineEdit_listenPort->text().toUInt();//端口
        QHostAddress  addr (IP) ;
        mTcpServer->listen(addr,port) ; //开始监听
        ui->plainTextEdit->appendPlainText ("**开始监听...") ;
        if(mTcpServer->isListening())
        {
            ui->plainTextEdit->appendPlainText ("**监听启动成功...") ;
            ui->plainTextEdit->appendPlainText ("**服务器地址: "  + mTcpServer->serverAddress().toString());
            ui->plainTextEdit->appendPlainText ("**服务器端口: " +QString::number (mTcpServer->serverPort())) ;
            ui->pushButton_startListen->setText("停止监听");
        }
        else{
            ui->plainTextEdit->appendPlainText ("**监听启动失败...") ;
        }
    }
}

void TcpServer::on_pushButton_sendMsg_clicked()
{
    if(mTcpSocket == nullptr)
    {
        ui->plainTextEdit->appendPlainText ("**客户端已断开，发送失败! ") ;
        return;
    }
    //发送一行字符串，以换行符结束
    QString msg=ui->lineEdit_editMsg->text() ;
    ui->plainTextEdit->appendPlainText ("[out] "+msg) ;
    ui->lineEdit_editMsg->clear() ;
    ui->lineEdit_editMsg->setFocus () ;

    QByteArray str=msg. toUtf8() ;
    str.append('\n');//添加一个换行符
    mTcpSocket->write(str) ;
}

void TcpServer::on_pushButton_CleanMsgBox_clicked()
{
    ui->plainTextEdit->clear();
}

void TcpServer::on_pushButton_Exit_clicked()
{
    this->hide();
}
